package com.zj;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

public class BankServer {
    private static Logger logger=Logger.getLogger(BankServer.class.getName());
    public static void main(String[] args) throws IOException {
        //CPU核心数
        int processorors=Runtime.getRuntime().availableProcessors();
        //核心线程池的大小
        int corePoolSize=processorors;
        //最大线程池的大小
        int maxPoolSize=processorors*2;
        //线程最大空闲时间
        long keepAliveTime=10;
        //时间单位
        TimeUnit unit= TimeUnit.SECONDS;
        //阻塞队列  容量为2  最多允许放入两个空闲任务
        BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(2);
        //线程创建工厂
        ThreadFactory threadFactory=new NameThreadFactory();
        //线程池拒绝策略
        RejectedExecutionHandler handler=new MyIgnorePolicy();
        ThreadPoolExecutor executor=null;

        executor=new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
        //预启动 所有核心线程  提升效率
        executor.prestartAllCoreThreads();

        Bank bank=new Bank();
        ServerSocket ss=new ServerSocket(12000);
        System.out.println("银行服务器启动成功"+ss.getLocalPort());
        boolean flag=true;
        while(flag){
            Socket s=ss.accept();
            logger.info("ATM客户端："+s.getRemoteSocketAddress()+"登录了服务器");

            BankTask task=new BankTask(s,bank);
            //提交任务到线程池
            executor.submit(task);
        }
        //关闭线程池
        executor.shutdown();
    }

    /*
    *
    * 线程工厂
    * */
    public static class NameThreadFactory implements ThreadFactory{
        // 线程id AtomicInteger 原子类  线程安全
        //并发编程的三个特性 原子性 可见性 有序性
        private final AtomicInteger mThreadNum = new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "线程-" + mThreadNum.getAndIncrement()); //线程的名称 先取值 再++
//            System.out.println(t.getName() + " 线程创建了");
            return t;
        }
    }
    /*
    * 线程池拒绝策略
    * */
    public static class MyIgnorePolicy implements RejectedExecutionHandler{
        private Logger logger=Logger.getLogger(MyIgnorePolicy.class.getName());
        // 拒绝策略
        @Override
        //                            被拒绝的任务     线程池对象
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            System.out.println("线程池拒绝策略");
        }

        private void doLog(Runnable runnable,ThreadPoolExecutor e){
            logger.warning("线程池拒绝策略"+e.toString()+runnable.toString()+"被拒绝执行");
        }
    }
}
